home *** CD-ROM | disk | FTP | other *** search
/ Aminet 7 / Aminet 7 - August 1995.iso / Aminet / comm / net / cslip_sana2.lha / slip / cslip.h < prev    next >
C/C++ Source or Header  |  1993-06-29  |  11KB  |  325 lines

  1. /*
  2.  * The code in this file is derived from and very similar to the example
  3.  * implementation provided in RFC 1144, and is therefore sort-of covered
  4.  * by its copyright:
  5.  *
  6.  * Copyright (C) 1989 Regents of the University of California.
  7.  *
  8.  * modified for KA9Q Internet Software Package by
  9.  * Katie Stevens (dkstevens@ucdavis.edu)
  10.  * University of California, Davis
  11.  * Computing Services
  12.  *    - 01-31-90    initial adaptation
  13.  *
  14.  *    - Feb 1991    Bill_Simpson@um.cc.umich.edu
  15.  *            variable number of conversation slots
  16.  *            allow zero or one slots
  17.  *            separate routines
  18.  *            status display
  19.  *
  20.  * This adaptation (for cslip.device) by Olaf 'Rhialto' Seibert.
  21.  */
  22.  
  23. /*
  24.  * Compressed packet format:
  25.  *
  26.  * The first octet contains the packet type (top 3 bits), TCP
  27.  * 'push' bit, and flags that indicate which of the 4 TCP sequence
  28.  * numbers have changed (bottom 5 bits).  The next octet is a
  29.  * conversation number that associates a saved IP/TCP header with
  30.  * the compressed packet.  The next two octets are the TCP checksum
  31.  * from the original datagram.    The next 0 to 15 octets are
  32.  * sequence number changes, one change per bit set in the header
  33.  * (there may be no changes and there are two special cases where
  34.  * the receiver implicitly knows what changed -- see below).
  35.  *
  36.  * There are 5 numbers which can change (they are always inserted
  37.  * in the following order): TCP urgent pointer, window,
  38.  * acknowlegement, sequence number and IP ID.  (The urgent pointer
  39.  * is different from the others in that its value is sent, not the
  40.  * change in value.)  Since typical use of SLIP links is biased
  41.  * toward small packets (see comments on MTU/MSS below), changes
  42.  * use a variable length coding with one octet for numbers in the
  43.  * range 1 - 255 and 3 octets (0, MSB, LSB) for numbers in the
  44.  * range 256 - 65535 or 0.  (If the change in sequence number or
  45.  * ack is more than 65535, an uncompressed packet is sent.)
  46.  */
  47.  
  48. /*
  49.  * Packet types (must not conflict with IP protocol version)
  50.  *
  51.  * The top nibble of the first octet is the packet type.  There are
  52.  * three possible types: IP (not proto TCP or tcp with one of the
  53.  * control flags set); uncompressed TCP (a normal IP/TCP packet but
  54.  * with the 8-bit protocol field replaced by an 8-bit connection id --
  55.  * this type of packet syncs the sender & receiver); and compressed
  56.  * TCP (described above).
  57.  *
  58.  * LSB of 4-bit field is TCP "PUSH" bit (a worthless anachronism) and
  59.  * is logically part of the 4-bit "changes" field that follows.  Top
  60.  * three bits are actual packet type.  For backward compatibility
  61.  * and in the interest of conserving bits, numbers are chosen so the
  62.  * IP protocol version number (4) which normally appears in this nibble
  63.  * means "IP packet".
  64.  */
  65.  
  66. typedef unsigned long  u_long;
  67. typedef unsigned int   u_int;
  68. typedef unsigned short u_short;
  69. typedef unsigned char  u_char;
  70.  
  71. typedef unsigned short int16;
  72. typedef unsigned long int32;
  73.  
  74. /* IP and TCP header format */
  75.  
  76. struct ip_header {
  77.     char v_ihl;        /* Version + IP header length */
  78. #define IPVERSION    4
  79.     char tos;        /* Type of service */
  80.     int16 length;        /* Total length */
  81.     int16 id;        /* Identification */
  82.     int16 fl_offs;        /* Flags + fragment offset */
  83.  
  84. #define F_OFFSET    0x1fff    /* Offset field */
  85. #define DF    0x4000        /* Don't fragment flag */
  86. #define MF    0x2000        /* More Fragments flag */
  87.  
  88.     char ttl;        /* Time to live */
  89.     char protocol;        /* Protocol */
  90.     int16 checksum;     /* Header checksum */
  91.     int32 source;        /* Source address */
  92.     int32 dest;        /* Destination address */
  93. };
  94.  
  95. /* TCP segment header */
  96. struct tcp_header {
  97.     int16 source;    /* Source port */
  98.     int16 dest;    /* Destination port */
  99.     int32 seq;    /* Sequence number */
  100.     int32 ack;    /* Acknowledgment number */
  101.     char offset;    /* Data offset */
  102.     char flags;    /* Flags, data offset */
  103. #define DSHIFT    4    /* Data offset field */
  104. #define DMASK    0x0f    /* Mask for normalized data offset field */
  105. #define URG    0x20    /* URGent flag */
  106. #define ACK    0x10    /* ACKnowledgment flag */
  107. #define PSH    0x08    /* PuSH flag */
  108. #define RST    0x04    /* ReSeT flag */
  109. #define SYN    0x02    /* SYNchronize flag */
  110. #define FIN    0x01    /* FINal flag */
  111.     int16 wnd;    /* Receiver flow control window */
  112.     int16 checksum; /* Header + data checksum */
  113.     int16 up;    /* Urgent pointer */
  114. };
  115.  
  116. /* IP protocol field values */
  117. #define TCP_PTCL    6    /* Transmission Control Protocol */
  118.  
  119. #define lonibble(x)     ((x) & 0x0F)
  120.  
  121. struct mbuf {
  122.     u_char *m_off;    /* pointer to start of data */
  123.     int    m_len;    /* length of data */
  124. };
  125. #define mtod(m, t)      ((t)(m->m_off))
  126.  
  127. /* Appendix A.1  Definitions and State Data */
  128.  
  129. #define MAX_STATES    16    /* must be >2 and <255 */
  130. #define MAX_HDR     128    /* max TCP+IP hdr length (by protocol def) */
  131.  
  132. /* packet types */
  133. #define TYPE_IP     0x40
  134. #define TYPE_UNCOMPRESSED_TCP 0x70
  135. #define TYPE_COMPRESSED_TCP 0x80
  136. #define TYPE_ERROR    0x00    /* this is not a type that ever appears on
  137.                  * the wire. The receive framer uses it to
  138.                  * tell the decompressor there was a packet
  139.                  * transmission error. */
  140. /*
  141.  * Bits in the first octet of the compressed packet
  142.  */
  143.  
  144. /* flag bits for what changed in a packet */
  145.  
  146. #define NEW_C        0x40    /* Connection id */
  147. #define NEW_I        0x20    /* IP ID field (change != 1) */
  148. #define TCP_PUSH_BIT    0x10    /* TCP PUSH bit */
  149.  
  150. #define NEW_S        0x08    /* Sequence number */
  151. #define NEW_A        0x04    /* Acknowledgement */
  152. #define NEW_W        0x02    /* Window size */
  153. #define NEW_U        0x01    /* Urgent pointer */
  154.  
  155. /* reserved, special-case values of above */
  156.  
  157. #define SPECIAL_I    (NEW_S|NEW_W|NEW_U)     /* echoed interactive traffic */
  158. #define SPECIAL_D    (NEW_S|NEW_A|NEW_W|NEW_U) /* unidirectional data */
  159. #define SPECIALS_MASK    (NEW_S|NEW_A|NEW_W|NEW_U)
  160.  
  161. /*
  162.  * "state" data for each active tcp conversation on the wire. This is
  163.  * basically a copy of the entire TCP/IP header from the last packet together
  164.  * with a small identifier the transmit & receive ends of the line use to
  165.  * locate the saved header.
  166.  */
  167. struct cstate {
  168.     struct cstate *cs_next; /* next most recently used cstate (xmit only) */
  169.     u_short cs_hlen;    /* size of hdr (receive only) */
  170.     u_char cs_id;        /* connection # associated with this state */
  171.     u_char cs_filler;
  172.     union {
  173.         u_char csu_hdr[MAX_HDR];
  174.         int32 csu_hdr4[1];
  175.         struct ip_header csu_ip; /* ip/tcp hdr from most recent packet */
  176.     } slcs_u;
  177. };
  178. #define cs_ip        slcs_u.csu_ip
  179. #define cs_hdr        slcs_u.csu_hdr
  180. #define cs_hdr4     slcs_u.csu_hdr4
  181.  
  182. /*
  183.  * all the state data for one serial line (we need one of these per line).
  184.  */
  185. struct slcompress {
  186.     struct cstate *tstate;    /* transmit connection states (array)*/
  187.     struct cstate *rstate;    /* receive connection states (array)*/
  188.  
  189.     u_char tslot_limit;    /* highest transmit slot id (0-l)*/
  190.     u_char rslot_limit;    /* highest receive slot id (0-l)*/
  191.  
  192.     struct cstate *last_cs; /* most recently used tstate */
  193.     u_char last_recv;    /* last received connection id */
  194.     u_char last_xmit;    /* last sent connection id */
  195.     u_char flags;
  196.  
  197.     u_long sls_o_nontcp;    /* outbound non-TCP packets */
  198.     u_long sls_o_tcp;    /* outbound TCP packets */
  199.     u_long sls_o_uncompressed;    /* outbound uncompressed packets */
  200.     u_long sls_o_compressed;/* outbound compressed packets */
  201.     u_long sls_o_searches;    /* searches for connection state */
  202.     u_long sls_o_misses;    /* times couldn't find conn. state */
  203.  
  204.     u_long sls_i_ip;    /* inbound non-TCP packets */
  205.     u_long sls_i_uncompressed;    /* inbound uncompressed packets */
  206.     u_long sls_i_compressed;/* inbound compressed packets */
  207.     u_long sls_i_error;    /* inbound error packets */
  208.     u_long sls_i_tossed;    /* inbound packets tossed because of error */
  209.  
  210.     signed char on;     /* ==SL_ON: on, >0: trycount, ==0: off */
  211. };
  212.  
  213. /* last_xmit/last_recv initial value */
  214. #define NO_CID        255
  215.  
  216. /* flag values */
  217. #define SLF_TOSS    1    /* tossing rcvd frames because of input err */
  218. #define SLF_ALLOWED    2    /* allow receiving compression */
  219. #define SLF_ON        4    /* use compression */
  220.  
  221. /* optional trycount feature */
  222. #define TRYCOUNT    3    /* try 3 TCP_UNCOMPRESSED packets */
  223. #define SL_ON        -1    /* use compression */
  224.  
  225. /*
  226.  * The following macros are used to encode and decode numbers. They all
  227.  * assume that 'cp' points to a buffer where the next byte encoded (decoded)
  228.  * is to be stored (retrieved). Since the decode routines do arithmetic,
  229.  * they have to convert from and to network byte order.
  230.  */
  231.  
  232. /*
  233.  * ENCODE encodes a number that is known to be non-zero. ENCODEZ checks for
  234.  * zero (zero has to be encoded in the long, 3 byte form).
  235.  */
  236.  
  237. #define ENCODE(n) { \
  238.     if ((u_short)(n) >= 256) { \
  239.         *cp++ = 0; \
  240.         cp[1] = (n); \
  241.         cp[0] = (n) >> 8; \
  242.         cp += 2; \
  243.     } else { \
  244.         *cp++ = (n); \
  245.     } \
  246.     }
  247.  
  248. #define ENCODEZ(n) { \
  249.     if ((u_short)(n) >= 256 || (u_short)(n) == 0) { \
  250.         *cp++ = 0; \
  251.         cp[1] = (n); \
  252.         cp[0] = (n) >> 8; \
  253.         cp += 2; \
  254.     } else { \
  255.         *cp++ = (n); \
  256.     } \
  257.     }
  258.  
  259. /*
  260.  * DECODEL takes the compressed change at byte cp and adds it to the
  261.  * current value of packet field 'f' (which must be a 4-byte (long) integer
  262.  * in the current network byte order). DECODES does the same for a 2-byte (short)
  263.  * field. DECODEU takes the change at cp and stuffs it into the (short) field f.
  264.  * 'cp' is updated to point to the next field in the compressed header.
  265.  */
  266.  
  267. #define DECODEL(f) { \
  268.     if (*cp == 0) { \
  269.         (f) = htonl(ntohl(f) + ((cp[1] << 8) | cp[2])); \
  270.         cp += 3; \
  271.     } else { \
  272.         (f) = htonl(ntohl(f) + (u_long)*cp++); \
  273.     } \
  274.     }
  275.  
  276. #define DECODES(f) { \
  277.     if (*cp == 0) { \
  278.         (f) = htons(ntohs(f) + ((cp[1] << 8) | cp[2])); \
  279.         cp += 3; \
  280.     } else { \
  281.         (f) = htons(ntohs(f) + (u_short)*cp++); \
  282.     } \
  283.     }
  284.  
  285. #define DECODEU(f) { \
  286.     if (*cp == 0) { \
  287.         (f) = htons(((cp[1] << 8) | cp[2])); \
  288.         cp += 3; \
  289.     } else { \
  290.         (f) = htons((u_short)*cp++); \
  291.     } \
  292.     }
  293.  
  294. #define BCOPY(s, d, l)  memcpy(d, s, l)
  295. #define BCMP(s, d, l)   memcmp(d, s, l)
  296.  
  297. #define htons(s)        (s)     /* on big-endian machines, that is */
  298. #define ntohs(s)        (s)
  299. #define htonl(l)        (l)
  300. #define ntohl(l)        (l)
  301.  
  302. /* Sana2 special stats values */
  303.  
  304. #define S2SS_CSLIP_O_NONTCP    ((S2WireType_CSLIP << 16) | 1)
  305. #define S2SS_CSLIP_O_TCP    ((S2WireType_CSLIP << 16) | 2)
  306. #define S2SS_CSLIP_O_UNCOMPRESSED   ((S2WireType_CSLIP << 16) | 3)
  307. #define S2SS_CSLIP_O_COMPRESSED ((S2WireType_CSLIP << 16) | 4)
  308. #define S2SS_CSLIP_O_SEARCHES    ((S2WireType_CSLIP << 16) | 5)
  309. #define S2SS_CSLIP_O_MISSES    ((S2WireType_CSLIP << 16) | 6)
  310.  
  311. #define S2SS_CSLIP_I_IP     ((S2WireType_CSLIP << 16) | 17)
  312. #define S2SS_CSLIP_I_UNCOMPRESSED   ((S2WireType_CSLIP << 16) | 18)
  313. #define S2SS_CSLIP_I_COMPRESSED ((S2WireType_CSLIP << 16) | 19)
  314. #define S2SS_CSLIP_I_ERROR    ((S2WireType_CSLIP << 16) | 20)
  315. #define S2SS_CSLIP_I_TOSSED    ((S2WireType_CSLIP << 16) | 21)
  316.  
  317. /* Prototypes for functions defined in cslip.c */
  318.  
  319. u_char sl_compress_tcp(struct mbuf *m, struct slcompress *comp);
  320. void sl_xmit_error(struct slcompress *comp);
  321. struct mbuf *sl_uncompress_tcp(struct mbuf *m, u_int type, struct slcompress *comp);
  322. void sl_compress_init(struct slcompress *comp, int, int);
  323. void sl_compress_deinit(struct slcompress *comp);
  324.  
  325.